Skip to content

Draft: Anisotropic friction#210

Open
antoinebou12 wants to merge 53 commits intoipc-sim:mainfrom
antoinebou12:anisotropic_friction
Open

Draft: Anisotropic friction#210
antoinebou12 wants to merge 53 commits intoipc-sim:mainfrom
antoinebou12:anisotropic_friction

Conversation

@antoinebou12
Copy link
Copy Markdown
Contributor

@antoinebou12 antoinebou12 commented Feb 4, 2026

Description

This PR adds anisotropic friction to IPC Toolkit’s tangential contact model: per-contact tangent-space velocity scaling and optional Erleben et al. (2019) “matchstick” / elliptical-L2 direction-dependent static and kinetic coefficients, with backward-compatible defaults.

The implementation follows a semi-implicit (lagged) coefficient approach: direction-dependent effective μ_s / μ_k are computed from the lagged state (using scaled tangential velocity τ_aniso = μ_aniso ⊙ τ) and stored on each TangentialCollision as mu_s_effective_lagged / mu_k_effective_lagged.

During force / gradient / Hessian / Jacobian evaluation, these coefficients are held fixed for that evaluation and recomputed only when the lagged state is refreshed (e.g., per Newton iteration).

This avoids in-evaluation ∂μ_eff/∂τ terms and ensures that the dissipative potential, force, and derivatives remain internally consistent within each lagged update, while remaining an approximation of a fully implicit anisotropic model.

Callers using directional anisotropy must explicitly invoke
TangentialCollisions::update_lagged_anisotropic_friction_coefficients(...)
after build and whenever lagged positions or velocities change.

Fixes #4.


Summary of changes

  • Per-collision parameters on TangentialCollision:

    • mu_aniso: tangent-axis scaling of slip (default (1,1) → isotropic behavior)
    • mu_s_aniso / mu_k_aniso: ellipse axes for directional friction (optional)
    • mu_s_effective_lagged / mu_k_effective_lagged: cached lagged coefficients
  • Pipeline behavior:

    1. Build tangential collisions (initialize lagged coefficients to scalar μ_s, μ_k)
    2. Set anisotropic parameters (mu_*_aniso, mu_aniso)
    3. Refresh lagged coefficients via update_lagged_anisotropic_friction_coefficients(...)
    4. Evaluate force / gradient / Hessian / Jacobian with fixed lagged μ
  • Derivatives:

    • Friction uses ‖τ_aniso‖ (or ‖u_aniso‖)
    • No chain rule through ∂μ_eff/∂τ inside derivatives
  • Extras:

    • Helper functions for matchstick effective μ
    • Python bindings
    • Tests (helpers, edge cases, Jacobians)
    • Docs + derivation notebook

Motivation

Many real interfaces are anisotropic (grain, brushing, weave).
This adds a local, per-contact model compatible with implicit solvers, while preserving default isotropic behavior.


Design note (why lagging)

Fully modeling μ(τ) inside a single dissipative potential is generally not compatible with a pure potential formulation due to non-zero curl in tangent space.

Using lagged coefficients:

  • Matches IPC’s existing design (lagged normals, bases, etc.)
  • Avoids inconsistent force/gradient behavior
  • Keeps implementation stable and practical

Limitations / follow-ups

  • Directional model active only in 2D tangent space (3D sims)
  • 2D sims remain isotropic
  • Current gating uses mu_s_aniso; cases with only mu_k_aniso may require extension

Dependencies

  • No new runtime dependencies
  • Optional: Jupyter for derivation notebook

How tested

cmake -S . -B build -DCMAKE_BUILD_TYPE=Release
cmake --build build --config Release
ctest --test-dir build -C Release
ctest --test-dir build -C Release -R friction

Environment: Windows 11, MSVC 2022


Risk

High — modifies core friction force / Jacobian / Hessian paths.
Incorrect usage of lagged updates may desynchronize force and derivatives.


Type of change

  • Enhancement
  • New feature (non-breaking)
  • Documentation

Checklist

  • Code follows style guidelines
  • Self-review completed
  • Documentation updated
  • Tests added and passing
  • No new warnings

antoinebou12 and others added 17 commits January 26, 2026 17:31
This commit introduces a new example script demonstrating the use of anisotropic friction in the IPC Toolkit. The script showcases the setup of a simple collision scenario, building normal and tangential collisions, assigning anisotropic friction coefficients, and computing effective friction for various velocity directions. Additionally, it compares the results with isotropic friction to highlight the differences in behavior.
… of effective friction coefficients and ensure finite results. Update documentation to reflect changes in function name and return values.
…nd improve clarity. Update documentation and tests to reflect changes from `anisotropic_mu_eff_sqrt_mu0_t0_sq_plus_mu1_t1_sq` to `anisotropic_mu_eff_f` and related functions.
…ility by consolidating function calls into single lines. This change enhances clarity without altering the test logic.
… and consistency. Convert markdown cells to code cells in the notebook, enhance symbolic variable definitions, and streamline friction force visualization. Update test cases to ensure consistent function calls and improve readability.
…move backward compatibility section from the tutorial, update execution counts in the notebook, and streamline function definitions in the C++ code. Enhance test cases for consistency and readability.
This commit introduces the Matchstick model for anisotropic friction, enhancing the IPC Toolkit's capabilities. Key changes include:

- Addition of the Matchstick model reference in `references.bib`.
- Updates to the C++ and Python API documentation to include anisotropic friction helpers and their usage.
- Enhancements in the `advanced_friction` tutorial to cover anisotropic friction features and their implementation.
- New tests for anisotropic friction transitions and effective coefficient calculations.

Documentation now references Erleben et al. (2019) for the model's derivation and implementation details.
…prove code comments for clarity in tangential collision and potential implementations.
@codecov
Copy link
Copy Markdown

codecov bot commented Feb 4, 2026

Codecov Report

❌ Patch coverage is 96.25668% with 7 lines in your changes missing coverage. Please review.
✅ Project coverage is 95.84%. Comparing base (9a704ea) to head (483bba6).

Files with missing lines Patch % Lines
src/ipc/potentials/tangential_potential.hpp 0.00% 6 Missing ⚠️
...pc/collisions/tangential/tangential_collisions.cpp 98.38% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #210      +/-   ##
==========================================
+ Coverage   95.77%   95.84%   +0.07%     
==========================================
  Files         159      160       +1     
  Lines       16521    16655     +134     
  Branches      927      944      +17     
==========================================
+ Hits        15823    15963     +140     
+ Misses        698      692       -6     
Flag Coverage Δ
unittests 95.84% <96.25%> (+0.07%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@zfergus
Copy link
Copy Markdown
Member

zfergus commented Feb 4, 2026

Woooow! This is really awesome. Thanks for the contribution. The matchstick method for anisotropic friction was something I was interested in implementing, so I am super excited you did it already. 😄

I'll review the changes in depth when I have some free time. 🚀

@zfergus zfergus added the enhancement New feature or request label Feb 4, 2026
@zfergus zfergus added this to the v1.6.0 milestone Feb 4, 2026
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds anisotropic friction support to IPC Toolkit’s tangential contact model by introducing per-collision anisotropy parameters, helper math for effective direction-dependent friction coefficients, Python bindings, and expanded docs/tests.

Changes:

  • Added anisotropic friction parameters on TangentialCollision (mu_aniso, mu_s_aniso, mu_k_aniso) and exposed them to Python.
  • Updated tangential friction potential/force/Jacobian computations to use anisotropically scaled tangential velocity and effective-μ helpers.
  • Added anisotropic effective-μ helper functions plus new/updated unit tests and documentation.

Reviewed changes

Copilot reviewed 17 out of 18 changed files in this pull request and generated 11 comments.

Show a summary per file
File Description
src/ipc/potentials/tangential_potential.cpp Integrates anisotropic scaling/effective-μ into friction potential and force/Jacobian computations.
src/ipc/friction/smooth_mu.hpp Declares new anisotropic effective-μ helpers and derivatives.
src/ipc/friction/smooth_mu.cpp Implements effective-μ evaluation and derivative helpers.
src/ipc/collisions/tangential/tangential_collision.hpp Adds per-collision anisotropy parameters to the tangential collision model.
python/src/friction/smooth_mu.cpp Exposes anisotropic effective-μ helpers to Python.
python/src/collisions/tangential/tangential_collision.cpp Exposes new tangential collision anisotropy fields to Python.
tests/src/tests/potential/test_friction_potential.cpp Updates friction potential FD tests to handle filtered meshes/displacement mapping.
tests/src/tests/friction/test_smooth_mu.cpp Adds unit tests for anisotropic effective-μ helpers and derivatives.
tests/src/tests/friction/test_force_jacobian.cpp Adjusts force/Jacobian tests for mesh sizing and adds coverage for no-μ paths.
tests/src/tests/friction/test_anisotropic_friction.cpp Adds new anisotropic friction tests (helpers + force/Jacobian scenarios).
tests/src/tests/friction/CMakeLists.txt Registers the new anisotropic friction test file.
docs/source/tutorials/advanced_friction.rst Adds an anisotropic friction tutorial section and usage examples.
docs/source/cpp-api/friction.rst Documents anisotropic helper APIs for C++.
docs/source/python-api/friction.rst Documents anisotropic helper APIs for Python.
docs/source/references.bib Adds the matchstick model citation.
docs/source/developers/tools.rst / docs/source/developers/style_guide.rst Clarifies formatting/tooling expectations (clang-format version/style).

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/ipc/potentials/tangential_potential.cpp Outdated
Comment thread tests/src/tests/potential/test_friction_potential.cpp Outdated
Comment thread tests/src/tests/friction/test_force_jacobian.cpp Outdated
Comment thread tests/src/tests/friction/test_force_jacobian.cpp Outdated
Comment thread tests/src/tests/friction/test_anisotropic_friction.cpp Outdated
Comment thread tests/src/tests/friction/test_anisotropic_friction.cpp Outdated
Comment thread src/ipc/collisions/tangential/tangential_collision.hpp
Comment thread src/ipc/friction/smooth_mu.cpp Outdated
Comment thread src/ipc/potentials/tangential_potential.cpp Outdated
@ipc-sim ipc-sim deleted a comment from Copilot AI Feb 6, 2026
@ipc-sim ipc-sim deleted a comment from Copilot AI Feb 6, 2026
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Update TangentialPotential::gradient to include contributions from the
gradients of effective mu_s and mu_k (direction-dependent friction),
obtaining grad_mu_* via anisotropic_mu_eff_f_grad and adding the
corresponding drift terms.

Add virtual mu_f0_grad_mu_s/mu_k declarations and provide
finite-difference
fallback implementations in friction_potential.hpp and
tangential_adhesion_potential.hpp.

Update tests: replace M_PI with igl::PI and add a test that verifies the
TangentialPotential gradient and Hessian against finite differences.

WARNING: tests fail because Hessian has not been updated to account for
anisotropic coefficients
Comment thread src/ipc/potentials/tangential_potential.cpp Outdated
Comment thread src/ipc/potentials/tangential_potential.cpp Outdated
Comment thread src/ipc/potentials/tangential_potential.cpp Outdated
Comment thread src/ipc/potentials/tangential_potential.cpp Outdated
@zfergus
Copy link
Copy Markdown
Member

zfergus commented Feb 24, 2026

Hi Antoine,

I’ve put together a document detailing the challenges of integrating anisotropic friction into a fully implicit framework: Anisotropic_IPC_Friction.pdf.

The core issue is that anisotropic coefficients create a nonzero curl on the tangent vector space. Because of this, we can't derive an incremental potential that perfectly matches the required forces. While the document proposes an approximate potential, I recommend lagging the anisotropic coefficients—similar to our current approach with normal forces and tangent bases—as a more practical path forward.

-Z

@antoinebou12
Copy link
Copy Markdown
Contributor Author

Hi Zachary,

Thanks for sharing the PDF, it clarified a lot for me, especially the curl issue (I hadn’t considered that case at all) and the lagged anisotropy approach.

I’ve been a bit busy with school lately, but I’m excited to get back to this. My current implementation is fairly naive, so I’ll likely rework it to better follow your formulation probably starting with the lagged version since it fits well with the existing codebase.

I’ll keep you posted once I have something close to working

Best,
Antoine

Antoine Boucher added 9 commits April 13, 2026 13:27
…ian BarrierPotential API

Made-with: Cursor
- Add mu_s_effective_lagged/mu_k_effective_lagged and TangentialCollisions
  reset/update methods; refresh after build and when slip changes.
- Use lagged scalars in dissipative potential, force, and Jacobians; remove
  ad-hoc d(mu)/d(tau) Jacobian terms and align smooth_contact jacobian with force.
- Python: expose lagged fields and update/reset on TangentialCollisions.
- Tests: BarrierPotential(dhat, kappa) and build API; call update for anisotropic
  cases; tighten combined FD check; add gradient vs -force test; extend smooth
  3D jacobian check with lagged anisotropic FD.
- Docs: advanced_friction lagging section and BarrierPotential build snippets.

Made-with: Cursor
- Removed the `anisotropic_mu_eff_f_grad` function from the C++ API and related documentation, as it is no longer needed for the lagged matchstick model.
- Updated documentation to clarify the use of lagged anisotropic friction coefficients in the Python API and tutorials.
- Adjusted tests to reflect changes in the friction model and ensure compatibility with the new API structure.
- Simplified function calls in `test_anisotropic_friction.cpp` and `test_force_jacobian.cpp` by removing unnecessary line breaks.
- Enhanced code clarity without altering functionality.
@antoinebou12 antoinebou12 changed the title Anisotropic friction Draft: Anisotropic friction Apr 15, 2026
@antoinebou12
Copy link
Copy Markdown
Contributor Author

Hi Zachary,

I updated the PR to use a semi-implicit (lagged) anisotropic friction mode. The directional effective coefficients are computed from the lagged state and then held fixed for each evaluation (and recomputed when the lagged state is refreshed, e.g., per Newton iteration).

This avoids in-evaluation ∂μ/∂τ terms and keeps the force, gradient, and Jacobian consistent within each lagged update, while remaining an approximation of the fully implicit anisotropic model.

I can either continue refining this PR or adjust the scope if you’d prefer a simpler direction

I’m not entirely sure which parts you’d like to prioritize or simplify.

If helpful, I can also open a follow-up PR, or we can iterate on this later.

Happy to adapt based on your feedback 👍

@zfergus zfergus requested review from Copilot and zfergus April 15, 2026 17:15
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 27 out of 29 changed files in this pull request and generated 11 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread python/src/friction/smooth_mu.cpp Outdated
Comment on lines +141 to +142
(mu_s_eff, mu_k_eff) along tau_dir. (0, 0) if inputs are zero
(isotropic fallback).
Copy link

Copilot AI Apr 15, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The Python docstring for anisotropic_mu_eff_f describes (0,0) as an "isotropic fallback", but this function only evaluates the elliptical formula along a direction; it doesn't apply scalar μ_s/μ_k when axes are zero. To avoid confusing API users, please clarify that isotropic fallback is handled elsewhere (e.g., via anisotropic_mu_eff_from_tau_aniso / lagged collision coefficients) and that (0,0) is just the result for zero axes.

Suggested change
(mu_s_eff, mu_k_eff) along tau_dir. (0, 0) if inputs are zero
(isotropic fallback).
(mu_s_eff, mu_k_eff) along tau_dir. If the anisotropic axes are
zero, this function returns (0, 0), which is just the result of
evaluating the directional elliptical model with zero axes.
Isotropic fallback, when desired, is handled elsewhere by
higher-level anisotropic friction routines.

Copilot uses AI. Check for mistakes.
Comment on lines +419 to 425
// F = -μ N f₁(‖τ_aniso‖)/‖τ_aniso‖ T τ_aniso
// NOTE: no_mu -> leave mu out of this function (i.e., assuming mu = 1)
return -collision.weight * N * mu_f1_over_norm_tau * T * tau;
// NOTE: Direction-dependent (matchstick) μ uses lagged scalars on the
// collision; refresh with TangentialCollisions::
// update_lagged_anisotropic_friction_coefficients.
return -collision.weight * N * mu_f1_over_norm_tau * T * tau_aniso;
}
Copy link

Copilot AI Apr 15, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TangentialPotential::force applies mu_aniso in τ_aniso but then multiplies by T * τ_aniso. With the potential defined on ‖τ_aniso‖, the chain rule requires an additional diag(mu_aniso) on the left (i.e., use T_aniso = T * diag(mu_aniso) in the force). As written, the force will be inconsistent with the updated gradient/Hessian paths that already use T_aniso.

Copilot uses AI. Check for mistakes.
Comment on lines +596 to +597
// + -μ N f₁(‖τ_aniso‖)/‖τ_aniso‖ T [∇τ_aniso]
J += N * mu_f1_over_norm_tau * T * jac_tau_aniso;
Copy link

Copilot AI Apr 15, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The final Jacobian term uses T * jac_tau_aniso, but for a force of the form ... * (T * diag(mu_aniso)) * tau_aniso the velocity-derivative term should use T_aniso * jac_tau_aniso (or equivalently multiply jac_tau_aniso by an additional diag(mu_aniso) before left-multiplying by T). Otherwise the Jacobian w.r.t. velocities will be missing one mu_aniso factor.

Suggested change
// + -μ N f₁(‖τ_aniso‖)/‖τ_aniso‖ T [∇τ_aniso]
J += N * mu_f1_over_norm_tau * T * jac_tau_aniso;
// + -μ N f₁(‖τ_aniso‖)/‖τ_aniso‖ T_aniso [∇τ_aniso]
J += N * mu_f1_over_norm_tau * T_aniso * jac_tau_aniso;

Copilot uses AI. Check for mistakes.
Comment on lines +802 to 809
const double mu_f1_over_norm_tau =
mu_f1_over_x(tau_aniso.norm(), mu_s, mu_k);

// F = -μ N f₁(‖tau_aniso‖)/‖tau_aniso‖ T tau_aniso
// NOTE: no_mu -> leave mu out of this function (i.e., assuming mu = 1)
return -collision.weight * (no_contact_force_multiplier ? 1.0 : N)
* mu_f1_over_norm_tau * T * tau;
* mu_f1_over_norm_tau * T * tau_aniso;
}
Copy link

Copilot AI Apr 15, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

smooth_contact_force() applies mu_aniso in tau_aniso but still multiplies by T * tau_aniso. For consistency with the potential/gradient definition (and with the earlier gradient/Hessian changes), the force should use T_aniso = T * diag(mu_aniso) on the left; otherwise mu_aniso scaling is effectively only applied once and will desynchronize force vs. derivatives.

Copilot uses AI. Check for mistakes.
Comment on lines +947 to +948
// + -μ N f₁(‖tau_aniso‖)/‖tau_aniso‖ T [∇tau_aniso]
J += f1_over_norm_tau * T * jac_tau_aniso;
Copy link

Copilot AI Apr 15, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The last term in smooth_contact_force_jacobian_unit() uses T * jac_tau_aniso, but if the force is ... * (T * diag(mu_aniso)) * tau_aniso then this should use T_aniso * jac_tau_aniso (or apply an additional diag(mu_aniso) to jac_tau_aniso before left-multiplying by T). Otherwise the velocity Jacobian will be missing one mu_aniso factor.

Suggested change
// + -μ N f₁(‖tau_aniso‖)/‖tau_aniso‖ T [∇tau_aniso]
J += f1_over_norm_tau * T * jac_tau_aniso;
// + -μ N f₁(‖tau_aniso‖)/‖tau_aniso‖ T_aniso [∇tau_aniso]
J += f1_over_norm_tau * T_aniso * jac_tau_aniso;

Copilot uses AI. Check for mistakes.
Comment thread src/ipc/friction/smooth_mu.hpp Outdated
Comment on lines +99 to +100
/// @note If mu_s_aniso and mu_k_aniso are zero vectors, the function returns
/// (0, 0), which triggers compatible isotropic behavior.
Copy link

Copilot AI Apr 15, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The note on anisotropic_mu_eff_f says that returning (0,0) for zero ellipse axes "triggers" isotropic behavior, but anisotropic_mu_eff_f itself just evaluates the ellipse formula and does not perform any isotropic fallback. Consider rewording to clarify that isotropic fallback is implemented by anisotropic_mu_eff_from_tau_aniso (or by callers) and that (0,0) is simply the ellipse result for zero axes.

Suggested change
/// @note If mu_s_aniso and mu_k_aniso are zero vectors, the function returns
/// (0, 0), which triggers compatible isotropic behavior.
/// @note If mu_s_aniso and mu_k_aniso are zero vectors, this function returns
/// (0, 0) as the direct result of the ellipse formula. Any isotropic
/// fallback is handled by anisotropic_mu_eff_from_tau_aniso or by the
/// caller.

Copilot uses AI. Check for mistakes.
Comment on lines +121 to +126
/// @brief Tangential anisotropy scaling in the collision's tangent basis.
/// @note Default (1,1) preserves current isotropic behavior.
/// Requires a_i > 0. Values scale tau before friction evaluation.
/// Used with mu_s_aniso/mu_k_aniso by the elliptical model in
/// ipc::smooth_mu.
Eigen::Vector2d mu_aniso = Eigen::Vector2d::Ones();
Copy link

Copilot AI Apr 15, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

mu_aniso is documented as requiring a_i > 0, but there is currently no validation/enforcement. Negative or zero components can make the scaled-speed norm non-physical and can introduce undefined behavior in derivatives. Consider adding an assert/clamp when computing tau_aniso (or in update_lagged_anisotropic_friction_coefficients) to enforce strictly positive entries.

Copilot uses AI. Check for mistakes.
Comment on lines 572 to +573
// Premultiplied values
const VectorMax12d T_times_tau = T * tau;
const VectorMax12d T_times_tau = T * tau_aniso;
Copy link

Copilot AI Apr 15, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In force_jacobian(), T_times_tau is computed as T * tau_aniso, but if the force uses T_aniso = T * diag(mu_aniso) then the premultiplied term should be T_aniso * tau_aniso (or equivalently T * (diag(mu_aniso) * tau_aniso)). Otherwise the Jacobian will not match the corrected force/gradient relationship for mu_aniso scaling.

Copilot uses AI. Check for mistakes.
Comment on lines +587 to 593
// + -μ N f₁(‖τ_aniso‖)/‖τ_aniso‖ [∇T] τ_aniso
if (need_jac_N_or_T) {
const VectorMax2d scaled_tau = N * mu_f1_over_norm_tau * tau;
const VectorMax2d scaled_tau = N * mu_f1_over_norm_tau * tau_aniso;
for (int i = 0; i < ndof; i++) {
// ∂J/∂xᵢ = ∂T/∂xᵢ * τ
// ∂J/∂xᵢ = ∂T/∂xᵢ * τ_aniso
J.col(i) += jac_T.col(i).reshaped(T.rows(), T.cols()) * scaled_tau;
}
Copy link

Copilot AI Apr 15, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the ∇T term of force_jacobian(), scaled_tau is based on tau_aniso, but if the force is ... * T_aniso * tau_aniso then this term should use ∂(T*diag(mu_aniso))/∂x which effectively adds another diag(mu_aniso) factor. As written, geometric derivatives w.r.t. X/Ut will be missing that extra mu_aniso scaling.

Copilot uses AI. Check for mistakes.
Comment on lines 928 to 930
// Premultiplied values
const VectorMaxNd T_times_tau = T * tau;
const VectorMaxNd T_times_tau = T * tau_aniso;

Copy link

Copilot AI Apr 15, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

smooth_contact_force_jacobian_unit() computes T_times_tau = T * tau_aniso, but with mu_aniso scaling the force should be ... * (T * diag(mu_aniso)) * tau_aniso. The premultiplied term (and the subsequent Jacobian assembly) should be updated to use T_aniso * tau_aniso to avoid missing an extra mu_aniso factor.

Copilot uses AI. Check for mistakes.
@ipc-sim ipc-sim deleted a comment from Copilot AI Apr 15, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants